package com.dogantekin.allseeingeye.map;

import java.util.ArrayList;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.location.Location;

import com.dogantekin.allseeingeye.util.LocationItem;
import com.dogantekin.allseeingeye.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

public class MapOverlay extends Overlay {
	Location   				currentLocation;
	ArrayList<LocationItem> targetLocations;
	int        				azimuth;
	int						pitch;
	int 					roll;
	Bitmap	   				redPin;
	Bitmap	   				greenPin;
	Paint	   				paint;
	Paint      				arcPaint;
	Paint					tapPaint;
	int		   				angleOfSight;
	int 					range;
	int						infoBarHeight;
	LocationItem			selectedItem;
	GeoPoint		 		tapPoint;	

	public MapOverlay(Resources resources) {
		redPin       = BitmapFactory.decodeResource(resources, R.drawable.marker_red);
		greenPin     = BitmapFactory.decodeResource(resources, R.drawable.marker_green);
		angleOfSight = Integer.parseInt(resources.getString(R.string.angleOfSight));
		range        = Integer.parseInt(resources.getString(R.string.range));
		paint 	     = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(Color.BLACK);	
		arcPaint     = new Paint(Paint.ANTI_ALIAS_FLAG);
		arcPaint.setARGB(90, 20, 20, 20);
		arcPaint.setStyle(Style.FILL_AND_STROKE);
		tapPaint  	 = new Paint(Paint.ANTI_ALIAS_FLAG);
		tapPaint.setColor(0xFFFF9900);
		infoBarHeight = 60;
	}
	
	public void setCurrentLocation(Location currentLocation) {
		this.currentLocation = currentLocation;
	}
	public void setTargetLocations(ArrayList<LocationItem> targetLocations) {
		this.targetLocations = targetLocations;
	}
	public void setAzimuth(int azimuth) {
		this.azimuth = azimuth;
	}
	public void setPitch(int pitch) {
		this.pitch = pitch;
	}
	public void setRoll(int roll) {
		this.roll = roll;
	}

	private double getAzimuthAngle() {
		double temp = azimuth - 90;
		if(temp < 0) {
			temp = 360 + temp;
		}
		return temp;
	}	

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		Projection projection   = mapView.getProjection();
		Point      pointScreen  = new Point();
		
		if(tapPoint != null) {
			projection.toPixels(tapPoint,pointScreen);
			canvas.drawCircle(pointScreen.x, pointScreen.y, 5, tapPaint);									
		}		
		if(targetLocations != null) {
			for (LocationItem location : targetLocations) {
				projection.toPixels(new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude()*1E6)),pointScreen);
				canvas.drawBitmap(greenPin, pointScreen.x-greenPin.getWidth()/2, pointScreen.y-greenPin.getHeight(), paint);
				location.setScreenX(pointScreen.x);
				location.setScreenY(pointScreen.y);
			}
		}	
		if(currentLocation != null) {
			projection.toPixels(new GeoPoint((int)(currentLocation.getLatitude()*1E6),(int)(currentLocation.getLongitude()*1E6)),pointScreen);
			arcPaint.setStyle(Style.STROKE);
			float radius = projection.metersToEquatorPixels(range)* (float)(1/ Math.cos(Math.toRadians(currentLocation.getLatitude())));
			canvas.drawCircle(pointScreen.x, pointScreen.y, radius, arcPaint);			
			arcPaint.setStyle(Style.FILL_AND_STROKE);
			canvas.drawArc(new RectF(pointScreen.x-radius,pointScreen.y-radius,pointScreen.x+radius,pointScreen.y+radius), (float)getAzimuthAngle()-angleOfSight/2, angleOfSight, true, arcPaint);
			canvas.drawBitmap(redPin, pointScreen.x-redPin.getWidth()/2, pointScreen.y-redPin.getHeight(), paint);			
		} 
		drawInformationBar(canvas, mapView.getHeight(), mapView.getWidth());
	}	
	
	private void drawInformationBar(Canvas canvas, int height, int width) {
		Paint informationBackground = new Paint(Paint.ANTI_ALIAS_FLAG);
		informationBackground.setARGB(200, 170, 194, 41);
		Paint informationText = new Paint(Paint.ANTI_ALIAS_FLAG);
		informationText.setColor(Color.WHITE);

		canvas.drawRect(0, height - infoBarHeight, width, height,informationBackground);
		String latitudeStr = "";
		String longitudeStr = "";
		String azimuthStr = "Azimuth : " + azimuth;
		String pitchStr = "Pitch : " + pitch;
		String rollStr = "Roll : " + roll;
		if (currentLocation == null) {
			latitudeStr = "Latitude unknown";
			longitudeStr = "Longitude unknown";
		} else {
			latitudeStr = "Latitude : " + currentLocation.getLatitude();
			longitudeStr = "Longitude : " + currentLocation.getLongitude();
		}
		canvas.drawText(latitudeStr, 0, height - 50, informationText);
		canvas.drawText(longitudeStr, 0, height - 40, informationText);
		canvas.drawText(azimuthStr, 0, height - 30, informationText);
		canvas.drawText(pitchStr, 0, height - 20, informationText);
		canvas.drawText(rollStr, 0, height - 10, informationText);

		if (selectedItem != null) {
			canvas.drawText(selectedItem.getName(), width / 2+40, height - 50,informationText);
			canvas.drawText(selectedItem.getPhone(), width / 2+40,height - 40, informationText);
			canvas.drawText(selectedItem.getUrl(), width / 2+40, height - 30,informationText);
			canvas.drawText(String.valueOf((int)selectedItem.calculateDistance(currentLocation))+"mt",width / 2+40, height - 20, informationText);
			if(selectedItem.getImage() != null) {
				canvas.drawBitmap(selectedItem.getImage(), null, new Rect(width/2-30,height-infoBarHeight,width/2+30,height), informationText);				
			}
		}
	}	
	
	@Override
	public boolean onTap(GeoPoint point, MapView mapView) {
		tapPoint				= point;
		Projection projection   = mapView.getProjection();
		Point      pointTap  	= new Point();
		projection.toPixels(point, pointTap);

		if(targetLocations != null) {
			for (LocationItem location : targetLocations) {
				Rect tempRect =  new Rect((int)location.getScreenX()-greenPin.getWidth()/2,(int)location.getScreenY()-greenPin.getHeight(),(int)location.getScreenX()+greenPin.getWidth()/2,(int)location.getScreenY());
				if(tempRect.contains(pointTap.x, pointTap.y)) {
					selectedItem = location;
					tapPoint	 = new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude()*1E6));
					break;
				}	
			}
		}
		return super.onTap(point, mapView);
	}	
}